import jssc.SerialPort

const val ID_VOL = (0x01).toByte()
const val ID_FREQ = (0x02).toByte()
const val ID_CURRENT = (0x03).toByte()
const val ID_VOL_SHIFT = (0x10).toByte()
const val ID_ON_OFF = (0x11).toByte()
const val ID_READ_ALL = (0x50).toByte()

fun getVolSettingBytes(vol: Float, address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = ID_VOL
    val intVol: Int = (vol * 10).toInt();
    val highByte: Byte = (intVol shr 8 and FF).toByte()
    val lowByte: Byte = (intVol and FF).toByte()
    byteArray[2] = lowByte
    byteArray[3] = highByte
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
    println(byteArray.hexStr())

    return byteArray
}
fun getFreqSettingBytes(f: Float, address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = ID_FREQ
    val intf: Int = (f * 10).toInt();
    val highByte: Byte = (intf shr 8 and FF).toByte()
    val lowByte: Byte = (intf and FF).toByte()
    byteArray[2] = lowByte
    byteArray[3] = highByte
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
    println(byteArray.hexStr())

    return byteArray
}
fun getCurrentSettingBytes(c: Float, address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = ID_CURRENT
    val intf: Int = (c * 10).toInt();
    val highByte: Byte = (intf shr 8 and FF).toByte()
    val lowByte: Byte = (intf and FF).toByte()
    byteArray[2] = lowByte
    byteArray[3] = highByte
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
    println(byteArray.hexStr())

    return byteArray
}
fun getOnOffBytes(on: Boolean, address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = ID_ON_OFF

    byteArray[2] = 0
    byteArray[3] = (if (on) 0xff else 0).toByte()
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
    println(byteArray.hexStr())

    return byteArray
}

fun getStatusBytes(address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = ID_READ_ALL

    byteArray[2] = 0
    byteArray[3] = 0
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
   // println(byteArray.hexStr())

    return byteArray
}
fun getReadOnOffBytes(address: Int): ByteArray {
    val byteArray = ByteArray(5)
    byteArray[0] = address.toByte()
    byteArray[1] = 0x50

    byteArray[2] = 0
    byteArray[3] = 0x10
    byteArray[4] = 0
    byteArray[4] = byteArray.sum8()
    // println(byteArray.hexStr())

    return byteArray
}

fun checkResp(byteArray: ByteArray, address: Int,size:Int=4): Int {
    if (byteArray.size != size)
        return -1
    if (byteArray[0] != address.toByte())
        return -2
    if (byteArray.sum8() != byteArray.last())
        return -3
    if (byteArray[1].toInt() == 0xff  )
        return -4
    return byteArray[1].toInt() and 0xFF
}

fun errCode(code: Int): String {
    return when (code) {
        -1 -> "长度错误"
        -2 -> "电源地址错误"
        -3 -> "校验和错误"
        -4 -> "操作失败"
        0x01 -> "设置电压成功"
        0x02 -> "设置频率成功"
        0x11 -> "启动/关闭 成功"
        0x80 -> "启动/关闭 成功"
        else -> "错误代码：$code"
    }
}

class Status {
    var vol: Float = 0.0f
    var freq: Float = 0.0f
    var current: Float = 0.0f
    var p: Float = 0.0f
    var pf: Float = 0.0f
    var onOff: Boolean = false
    var vailed: Boolean = false


}
@Synchronized
fun setVol(serialPort: SerialPort, vol: Float, address: Int): Boolean {

    val b = getVolSettingBytes(vol,address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(4,1000);
        return checkResp(byteArray,address)>0

    } catch (e: Exception) {
        e.printStackTrace()
    }

    return false
}
@Synchronized
fun setFreq(serialPort: SerialPort, freq: Float, address: Int): Boolean {

    val b = getFreqSettingBytes(freq,address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(4,1000);
        println(byteArray.hexStr())
        return checkResp(byteArray,address)>0

    } catch (e: Exception) {
        e.printStackTrace()
    }

    return false
}
@Synchronized
fun setCurrent(serialPort: SerialPort, current: Float, address: Int): Boolean {

    val b = getCurrentSettingBytes(current,address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(4,1000);
        println(byteArray.hexStr())
        return checkResp(byteArray,address)>0

    } catch (e: Exception) {
        e.printStackTrace()
    }

    return false
}
@Synchronized
fun setOnoff(serialPort: SerialPort, onOff: Boolean, address: Int): Int {

    val b = getOnOffBytes(onOff,address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(4,1000);
        println(byteArray.hexStr())
       if( (byteArray[1].toInt()and 0xff) ==0x80){
           byteArray[1]=0x11
        }

        return checkResp(byteArray,address)

    } catch (e: Exception) {
        e.printStackTrace()
    }

    return 0
}
@Synchronized
fun readStatus(serialPort: SerialPort, address: Int): Status {
    val status = Status()

    val b = getStatusBytes(address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(13,1000);
        //println(byteArray.hexStr())
        if (byteArray.size != 13)
            return status
        if (byteArray[0] != address.toByte())
            return status
        if (byteArray[1].toInt() != 0x50)
            return status
        if (byteArray.sum8() != byteArray.last())
            return status

        status.vailed = true
        status.vol = ((byteArray[2].toInt() and 0xFF ) + (byteArray[3].toInt() shl 8 and 0xFF00))*0.1f
        status.freq = ((byteArray[4].toInt() and 0xFF) + ((byteArray[5].toInt() shl 8) and 0xFF00))*0.1f
        status.current = ((byteArray[6].toInt() and 0xFF) + (byteArray[7].toInt() shl 8 and 0xFF00))*0.01f
        status.p = ((byteArray[8].toInt() and 0xFF) + (byteArray[9].toInt() shl 8 and 0xFF00)).div(10)*10f
        status.pf = ((byteArray[10].toInt() and 0xFF) + (byteArray[11].toInt() shl 8 and 0xFF00)).div(10)*0.1f
        status.onOff=readOnoff(serialPort,address)==1
    } catch (e: Exception) {
        e.printStackTrace()
        status.vailed = false
    }

    return status
}
@Synchronized
fun readOnoff(serialPort: SerialPort,  address: Int): Int {

    val b = getReadOnOffBytes( address)
    serialPort.writeBytes(b)
    try {
        val byteArray=serialPort.readBytes(5,1000);
        //println(byteArray.hexStr())
        if(checkResp(byteArray,address,5)>0){
            return  byteArray[3].toInt() and 0xff
        }else{
            return -10
        }


    } catch (e: Exception) {
        e.printStackTrace()
    }
    return -10

}
